package com.ssy.lingxi.platform.template.service.serviceimpl.adorn;

import cn.hutool.core.collection.CollectionUtil;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.template.service.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.template.service.constant.SelectStatusEnum;
import com.ssy.lingxi.platform.template.service.entity.adorn.Advert;
import com.ssy.lingxi.platform.template.service.entity.adorn.PageTemplate;
import com.ssy.lingxi.platform.template.service.entity.adorn.PageTemplateCategory;
import com.ssy.lingxi.platform.template.service.entity.adorn.PageTemplateGoods;
import com.ssy.lingxi.platform.template.service.model.dto.adorn.AdvertDTO;
import com.ssy.lingxi.platform.template.service.model.dto.adorn.CategoryAdornDTO;
import com.ssy.lingxi.platform.template.service.model.dto.adorn.SaveAdvertDTO;
import com.ssy.lingxi.platform.template.service.model.dto.adorn.SaveTemplateAdornDTO;
import com.ssy.lingxi.platform.template.service.model.dto.common.MemberIdDTO;
import com.ssy.lingxi.platform.template.service.model.dto.web.RecommendDTO;
import com.ssy.lingxi.platform.template.service.model.vo.adorn.BrandVO;
import com.ssy.lingxi.platform.template.service.model.vo.adorn.CategoryAdornVO;
import com.ssy.lingxi.platform.template.service.model.vo.adorn.CategoryVO;
import com.ssy.lingxi.platform.template.service.model.vo.adorn.GoodsVO;
import com.ssy.lingxi.platform.template.service.repository.AdvertRepository;
import com.ssy.lingxi.platform.template.service.repository.PageTemplateCategoryRepository;
import com.ssy.lingxi.platform.template.service.repository.PageTemplateGoodsRepository;
import com.ssy.lingxi.platform.template.service.repository.PageTemplateRepository;
import com.ssy.lingxi.platform.template.service.service.adorn.WebChannelService;
import com.ssy.lingxi.search.api.feign.ITemplateChannelFeign;
import com.ssy.lingxi.search.api.model.request.channel.TemplateChannelCommoditySearchRequest;
import com.ssy.lingxi.search.api.model.response.BrandResponse;
import com.ssy.lingxi.search.api.model.response.CategoryResponse;
import com.ssy.lingxi.search.api.model.response.channel.ChannelCommoditySearchResponse;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 模板装修 - WEB渠道装修 - 业务实现层
 *
 * @author fhj
 * @version 2.0.0
 * @date 2020/12/25
 */
@Slf4j
@Service
public class WebChannelServiceImpl implements WebChannelService {

    @Resource
    private PageTemplateRepository pageTemplateRepository;
    @Resource
    private AdvertRepository advertRepository;
    @Resource
    private ITemplateChannelFeign templateChannelFeign;
    @Resource
    private PageTemplateCategoryRepository pageTemplateCategoryRepository;
    @Resource
    private PageTemplateGoodsRepository pageTemplateGoodsRepository;

    @Override
    @ApiOperation(value = "获取所有一级会员品类")
    public Wrapper<List<CategoryVO>> findAllFirstCategory(MemberIdDTO dto, Long shopId) {
        //调用搜索服务 -> 获取会员一级品类信息
        Wrapper<List<CategoryResponse>> wrapper = templateChannelFeign.getFirstCategoryListByMemberId(shopId, dto.getMemberId());
        if (wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.info("请求搜索服务失败:{}", wrapper.getMessage());
            return Wrapper.fail(ResponseCode.SERVICE_SEARCH_ERROR);
        }
        if (CollectionUtil.isEmpty(wrapper.getData())) {
            log.info("搜索服务返回的数据为:{}", wrapper.getData());
            return Wrapper.success(new ArrayList<>());
        }

        //拼装
        return Wrapper.success(wrapper.getData().stream().map(c -> {
            CategoryVO categoryVO = new CategoryVO();
            categoryVO.setCategoryId(c.getId());
            categoryVO.setCategoryName(c.getName());
            categoryVO.setId(c.getId());
            categoryVO.setName(c.getName());
            return categoryVO;
        }).collect(Collectors.toList()));
    }

    @Override
    @ApiOperation(value = "会员品类的装修内容")
    public Wrapper<CategoryAdornVO> memberCategoryAdorn(CategoryAdornDTO dto, UserLoginCacheDTO user) {
        //根据模板ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getTemplateId()).orElse(new PageTemplate());

        //装修的渠道商会员ID与角色ID
        Long adornMemberId;
        Long adornMemberRoleId;
        //装修的渠道商下级会员ID与角色ID
        Long subMemberId;
        Long subMemberRoleId;

        if (user.getMemberRoleType().equals(RoleTypeEnum.SERVICE_PROVIDER.getCode())) {
            adornMemberId = user.getMemberId();
            adornMemberRoleId = user.getMemberRoleId();
            subMemberId = dto.getMemberId();
            subMemberRoleId = dto.getRoleId();
        } else {
            List<Long> upperChannelMemberIds = user.getUpperChannelMemberIds();
            if (!upperChannelMemberIds.contains(dto.getMemberId())) {
                throw new BusinessException(ResponseCode.SEARCH_JOIN_UPPER_CHANNEL_NOT_EXIST);
            }

            adornMemberId = dto.getMemberId();
            adornMemberRoleId = dto.getRoleId();
            subMemberId = user.getMemberId();
            subMemberRoleId = user.getMemberRoleId();
        }

        //返回实体类
        CategoryAdornVO vo = new CategoryAdornVO();

        //封装二级会员品类、品类广告图
        PageTemplateCategory pageTemplateCategory = pageTemplateCategoryRepository.findByTemplateIdAndCategoryIdAndMemberId(dto.getTemplateId(), dto.getCategoryId(), adornMemberId);
        if (pageTemplateCategory != null) {
            vo.setCategoryAdvertPicUrl(pageTemplateCategory.getAdvertPicUrl());
            if (CollectionUtil.isNotEmpty(pageTemplateCategory.getTwoCategoryIds())) {
                Wrapper<List<CategoryResponse>> wrapper = templateChannelFeign.getSecondCategoryListByMemberId(pageTemplate.getShopId(), adornMemberId, pageTemplateCategory.getCategoryId());
                if (wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                    log.info("请求搜索服务失败:{}", wrapper.getMessage());
                    return Wrapper.fail(ResponseCode.SERVICE_SEARCH_ERROR);
                }
                if (CollectionUtil.isNotEmpty(wrapper.getData())) {
                    vo.setCategoryBOList(
                            wrapper.getData().stream()
                                    .filter(c1 -> pageTemplateCategory.getTwoCategoryIds().stream().anyMatch(c2 -> c2.equals(c1.getId())))
                                    .map(c3 -> {
                                        CategoryVO categoryVO = new CategoryVO();
                                        categoryVO.setCategoryId(c3.getId());
                                        categoryVO.setCategoryName(c3.getName());
                                        categoryVO.setSelectStatus(CommonBooleanEnum.YES.getCode());
                                        return categoryVO;
                                    }).collect(Collectors.toList())
                    );
                }
            }
        }

        //封装商品
        PageTemplateGoods pageTemplateGoods = pageTemplateGoodsRepository.findByTemplateIdAndCategoryIdAndMemberId(dto.getTemplateId(), dto.getCategoryId(), adornMemberId);
        if (pageTemplateGoods != null && CollectionUtil.isNotEmpty(pageTemplateGoods.getGoodsIds())) {
            TemplateChannelCommoditySearchRequest searchRequest = new TemplateChannelCommoditySearchRequest();
            searchRequest.setCurrent(1);
            searchRequest.setPageSize(10);
            searchRequest.setShopId(pageTemplate.getShopId());
            searchRequest.setCustomerCategoryId(dto.getCategoryId());
            searchRequest.setMemberId(adornMemberId);
            searchRequest.setMemberRoleId(adornMemberRoleId);
            searchRequest.setLoginMemberId(!Objects.equals(subMemberId, adornMemberId) ? subMemberId : null);
            searchRequest.setLoginMemberRoleId(!Objects.equals(subMemberId, adornMemberId) ? subMemberRoleId : null);
            searchRequest.setIdInList(pageTemplateGoods.getGoodsIds());
            searchRequest.setProvinceCode(dto.getProvinceCode());
            searchRequest.setCityCode(dto.getCityCode());
            Wrapper<PageData<ChannelCommoditySearchResponse>> wrapper = templateChannelFeign.searchCommodityList(searchRequest);
            if (wrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
                log.info("请求搜索服务失败:{}", wrapper.getMessage());
                return Wrapper.fail(ResponseCode.SERVICE_SEARCH_ERROR);
            }
            if (wrapper.getData() != null) {
                List<ChannelCommoditySearchResponse> templateResponseList = wrapper.getData().getData();
                if (!CollectionUtil.isEmpty(templateResponseList)) {
                    //筛选有效的商品ID（装修时选择的商品有可能被商家进行下架或删除, 只展示上架的商品）
                    List<Long> goodsIds = pageTemplateGoods.getGoodsIds().stream()
                            .filter(a -> templateResponseList.stream().map(ChannelCommoditySearchResponse::getId).collect(Collectors.toList()).contains(a))
                            .collect(Collectors.toList());

                    //拼装
                    vo.setGoodsBOList(
                            templateResponseList.stream().map(goods -> {
                                GoodsVO goodsVO = new GoodsVO();
                                goodsVO.setGoodsId(goods.getId());
                                goodsVO.setGoodsName(goods.getName());
                                goodsVO.setGoodsPicUrl(goods.getMainPic());
                                goodsVO.setGoodsPrice(goods.getMin() != null ? goods.getMin().toString() : null);
                                goodsVO.setCategoryName(goods.getCustomerCategory().getName());
                                goodsVO.setBrandName(goods.getBrand() != null ? goods.getBrand().getName() : null);
                                goodsVO.setMemberId(goods.getMemberId());
                                goodsVO.setMemberRoleId(goods.getMemberRoleId());
                                goodsVO.setShopId(goods.getStoreId());
                                goodsVO.setPriceType(goods.getPriceType());
                                goodsVO.setChannelSold(goods.getSold());
                                goodsVO.setTagList(goods.getTagList());
                                return goodsVO;
                            }).sorted(Comparator.comparingInt(a -> goodsIds.indexOf(a.getGoodsId()))).collect(Collectors.toList())
                    );
                }
            }
        }

        return Wrapper.success(vo);
    }

    @Override
    @ApiOperation(value = "根据类型获取广告")
    public Wrapper<List<Advert>> findAdvertsByType(AdvertDTO dto) {
        return Wrapper.success(advertRepository.findByTemplateIdAndTypeAndMemberId(dto.getTemplateId(), dto.getType(), dto.getMemberId()));
    }

    @Override
    @ApiOperation(value = "获取商品列表")
    public Wrapper<PageData<GoodsVO>> findGoodsList(RecommendDTO dto, UserLoginCacheDTO user) {
        //获取模板关联的商品
        PageTemplateGoods pageTemplateGoods = pageTemplateGoodsRepository.findByTemplateIdAndCategoryIdAndMemberId(dto.getTemplateId(), dto.getCategoryId(), user.getMemberId());
        List<Long> goodsIds = pageTemplateGoods != null && CollectionUtil.isNotEmpty(pageTemplateGoods.getGoodsIds()) ? pageTemplateGoods.getGoodsIds() : null;

        //根据模板ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getTemplateId()).orElse(new PageTemplate());

        /*
            调用搜索服务 -> 查询商品信息接口:
               0.未选择 根据商品ID查出不包含的商品
               1.已选择 根据商品ID查出包含的商品
               2.所有  查出所有
        */
        Wrapper<PageData<ChannelCommoditySearchResponse>> wrapper = null;
        if (dto.getType().equals(SelectStatusEnum.UNSELECTED.getCode())) {
            TemplateChannelCommoditySearchRequest searchRequest = new TemplateChannelCommoditySearchRequest();
            searchRequest.setCurrent(dto.getCurrent());
            searchRequest.setPageSize(dto.getPageSize());
            searchRequest.setShopId(dto.getShopId() != null ? dto.getShopId() : pageTemplate.getShopId());
            searchRequest.setCustomerCategoryId(dto.getTwoCategoryId() != null ? dto.getTwoCategoryId() : dto.getCategoryId());
            searchRequest.setBrandId(dto.getBrandId());
            searchRequest.setMemberId(user.getMemberId());
            searchRequest.setMemberRoleId(user.getMemberRoleId());
            searchRequest.setName(dto.getGoodsName());
            searchRequest.setIdNotInList(goodsIds);
            searchRequest.setProvinceCode(dto.getProvinceCode());
            searchRequest.setCityCode(dto.getCityCode());
            wrapper = templateChannelFeign.searchCommodityList(searchRequest);
        }
        if (dto.getType().equals(SelectStatusEnum.SELECTED.getCode())) {
            if (goodsIds == null) {
                return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
            }
            TemplateChannelCommoditySearchRequest searchRequest = new TemplateChannelCommoditySearchRequest();
            searchRequest.setCurrent(dto.getCurrent());
            searchRequest.setPageSize(dto.getPageSize());
            searchRequest.setShopId(dto.getShopId() != null ? dto.getShopId() : pageTemplate.getShopId());
            searchRequest.setCustomerCategoryId(dto.getTwoCategoryId() != null ? dto.getTwoCategoryId() : dto.getCategoryId());
            searchRequest.setBrandId(dto.getBrandId());
            searchRequest.setMemberId(user.getMemberId());
            searchRequest.setMemberRoleId(user.getMemberRoleId());
            searchRequest.setName(dto.getGoodsName());
            searchRequest.setIdInList(goodsIds);
            searchRequest.setProvinceCode(dto.getProvinceCode());
            searchRequest.setCityCode(dto.getCityCode());
            wrapper = templateChannelFeign.searchCommodityList(searchRequest);
        }

        //校验返回结果
        if (wrapper == null || wrapper.getData() == null || CollectionUtil.isEmpty(wrapper.getData().getData())) {
            return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
        }

        //拼装
        return Wrapper.success(new PageData<>(wrapper.getData().getTotalCount(), wrapper.getData().getData().stream().map(goods -> {
            GoodsVO goodsVO = new GoodsVO();
            goodsVO.setGoodsId(goods.getId());
            goodsVO.setGoodsPicUrl(goods.getMainPic());
            goodsVO.setGoodsName(goods.getName());
            goodsVO.setGoodsSlogan(goods.getSlogan());
            goodsVO.setGoodsPoints(goods.getSellingPoint());
            goodsVO.setCategoryName(goods.getCustomerCategory().getName());
            goodsVO.setBrandName(goods.getBrand() != null ? goods.getBrand().getName() : null);
            goodsVO.setPriceRange(goods.getMin() + "~" + goods.getMax());
            goodsVO.setSupplier(goods.getMemberName());
            goodsVO.setPriceType(goods.getPriceType());
            goodsVO.setChannelSold(goods.getSold());
            return goodsVO;
        }).collect(Collectors.toList())));
    }

    @Override
    @ApiOperation(value = "获取品类列表")
    public Wrapper<CategoryAdornVO> findCategoryList(RecommendDTO dto, UserLoginCacheDTO user) {
        //根据模板ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getTemplateId()).orElse(new PageTemplate());

        //获取模板关联的品类
        PageTemplateCategory pageTemplateCategory = pageTemplateCategoryRepository.findByTemplateIdAndCategoryIdAndMemberId(dto.getTemplateId(), dto.getCategoryId(), user.getMemberId());

        //调用搜索服务 -> 根据一级会员品类ID获取二级会员品类
        Wrapper<List<CategoryResponse>> wrapper = templateChannelFeign.getSecondCategoryListByMemberId(pageTemplate.getShopId(), user.getMemberId(), dto.getCategoryId());

        //封装二级会员品类信息和品类广告图
        CategoryAdornVO vo = new CategoryAdornVO();
        if (CollectionUtil.isNotEmpty(wrapper.getData())) {
            vo.setCategoryBOList(
                    wrapper.getData().stream().map(sc -> {
                        CategoryVO categoryVO = new CategoryVO();
                        categoryVO.setCategoryId(sc.getId());
                        categoryVO.setCategoryName(sc.getName());
                        categoryVO.setSelectStatus(pageTemplateCategory != null ? pageTemplateCategory.getTwoCategoryIds().contains(sc.getId()) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode() : CommonBooleanEnum.NO.getCode());
                        return categoryVO;
                    }).collect(Collectors.toList())
            );
        }
        if (pageTemplateCategory != null) {
            vo.setAdvertPicUrl(pageTemplateCategory.getAdvertPicUrl());
        }

        return Wrapper.success(vo);
    }

    @Override
    @ApiOperation(value = "获取品牌列表（下拉框）")
    public Wrapper<PageData<BrandVO>> findBrandList(RecommendDTO dto, UserLoginCacheDTO user) {
        //根据模板ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getTemplateId()).orElse(new PageTemplate());

        //调用搜索服务 -> 查询品牌信息
        Wrapper<PageData<BrandResponse>> wrapper = templateChannelFeign.getBrandList(1, 100, pageTemplate.getShopId(), dto.getCategoryId(), null, user.getMemberId(), user.getMemberRoleId(), null, null, null, null);
        if (wrapper.getData() == null || CollectionUtil.isEmpty(wrapper.getData().getData())) {
            return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
        }

        //拼装
        return Wrapper.success(new PageData<>(wrapper.getData().getTotalCount(), wrapper.getData().getData().stream().map(brand -> {
            BrandVO brandVO = new BrandVO();
            brandVO.setBrandId(brand.getId());
            brandVO.setBrandLogo(brand.getLogoUrl());
            brandVO.setBrandName(brand.getName());
            return brandVO;
        }).collect(Collectors.toList())));
    }

    @Override
    @Transactional
    @ApiOperation(value = "保存广告")
    public Wrapper<Void> saveAdvert(SaveAdvertDTO dto, UserLoginCacheDTO user) {
        advertRepository.deleteByTemplateIdAndTypeAndMemberIdAndRoleId(dto.getTemplateId(), dto.getType(), user.getMemberId(), user.getMemberRoleId());
        advertRepository.saveAll(dto.getAdverts().stream().peek(a -> {
            a.setMemberId(user.getMemberId());
            a.setRoleId(user.getMemberRoleId());
        }).collect(Collectors.toList()));
        return Wrapper.success();
    }

    @Override
    @Transactional
    @ApiOperation(value = "保存商品")
    public Wrapper<Void> saveGoods(SaveTemplateAdornDTO dto, UserLoginCacheDTO user) {
        PageTemplateGoods pageTemplateGoods = pageTemplateGoodsRepository.findByTemplateIdAndCategoryIdAndMemberId(dto.getTemplateId(), dto.getCategoryId(), user.getMemberId());
        pageTemplateGoods = pageTemplateGoods != null ? pageTemplateGoods : new PageTemplateGoods();
        pageTemplateGoods.setMemberId(user.getMemberId());
        pageTemplateGoods.setRoleId(user.getMemberRoleId());
        pageTemplateGoods.setTemplateId(dto.getTemplateId());
        pageTemplateGoods.setCategoryId(dto.getCategoryId());
        pageTemplateGoods.setGoodsIds(dto.getGoodsIds());
        pageTemplateGoodsRepository.saveAndFlush(pageTemplateGoods);
        return Wrapper.success();
    }

    @Override
    @Transactional
    @ApiOperation(value = "保存品类")
    public Wrapper<Void> saveCategory(SaveTemplateAdornDTO dto, UserLoginCacheDTO user) {
        PageTemplateCategory pageTemplateCategory = pageTemplateCategoryRepository.findByTemplateIdAndCategoryIdAndMemberId(dto.getTemplateId(), dto.getCategoryId(), user.getMemberId());
        pageTemplateCategory = pageTemplateCategory != null ? pageTemplateCategory : new PageTemplateCategory();
        pageTemplateCategory.setMemberId(user.getMemberId());
        pageTemplateCategory.setRoleId(user.getMemberRoleId());
        pageTemplateCategory.setTemplateId(dto.getTemplateId());
        pageTemplateCategory.setCategoryId(dto.getCategoryId());
        pageTemplateCategory.setAdvertPicUrl(dto.getCategoryAdvertPicUrl());
        pageTemplateCategory.setTwoCategoryIds(dto.getTwoCategoryIds());
        pageTemplateCategory.setIsShow(dto.getIsShow());
        pageTemplateCategoryRepository.saveAndFlush(pageTemplateCategory);
        return Wrapper.success();
    }
}
